package com.luo.d3s.ext.component.bus;

import com.luo.d3s.core.application.service.ApplicationService;
import com.luo.d3s.core.domain.adpator.Acl;
import com.luo.d3s.core.domain.adpator.Repository;
import com.luo.d3s.core.domain.service.DomainService;
import com.luo.d3s.core.domain.service.specifcation.Specification;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 领域对象注册中心 - 根据类型获取对应的注册实例
 *
 * @author luohq
 * @date 2023-01-18
 */
@Component
public class DomainRegistry implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        DomainRegistry.applicationContext = applicationContext;
    }


    public static <T extends ApplicationService> T applicationService(Class<T> appServiceClass) {
        return getBean(appServiceClass);
    }

    public static <T extends DomainService> T domainService(Class<T> domainServiceClass) {
        return getBean(domainServiceClass);
    }

    public static <T extends Specification> T specification(Class<T> specClass) {
        return getBean(specClass);
    }

    public static <T extends Repository> T repository(Class<T> repoClass) {
        return getBean(repoClass);
    }

    public static <T extends Acl> T acl(Class<T> aclClass) {
        return getBean(aclClass);
    }

    public static <T> T getBean(Class<T> targetClass) {
        T beanInstance = null;
        //优先按type查
        try {
            beanInstance = (T) applicationContext.getBean(targetClass);
        } catch (Exception e) {
        }
        //按name查
        if (beanInstance == null) {
            String simpleName = targetClass.getSimpleName();
            //首字母小写
            simpleName = Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
            beanInstance = (T) applicationContext.getBean(simpleName);
        }
        if (beanInstance == null) {
            throw new RuntimeException("Component " + targetClass + " can not be found in Spring Container");
        }
        return beanInstance;
    }

    public static <T> Map<String, T> getBeans(Class<T> targetClass) {
        return DomainRegistry.applicationContext.getBeansOfType(targetClass);
    }

    //public static Object getBean(String className) {
    //    return DomainRegistry.applicationContext.getBean(className);
    //}
    //
    //public static <T> T getBean(String name, Class<T> requiredType) {
    //    return DomainRegistry.applicationContext.getBean(name, requiredType);
    //}
    //
    //public static <T> T getBean(Class<T> requiredType, Object... params) {
    //    return DomainRegistry.applicationContext.getBean(requiredType, params);
    //}
    //
    //public static ApplicationContext getApplicationContext() {
    //    return applicationContext;
    //}
}
